/**h* SpringProxAPI/ISO15693
 *
 * NAME
 *   SpringProxAPI :: ISO 15693
 *
 * DESCRIPTION
 *   Implementation of ISO/IEC 15693 (and ICODE1)
 *
 **/

/*

  SpringProx API
  --------------

  Copyright (c) 2000-2008 SpringCard - www.springcard.com

  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.

  History
  -------
 
  LTX 26/02/2008 : created
  
*/
#include "sprox_api_i.h"

#include "micore_picc.h"

SWORD Save15693Snr(SPROX_PARAM  BYTE snr[8])
{
  SPROX_PARAM_TO_CTX;
  SPROX_Trace(TRACE_DEBUG, "15693Snr <- %02X%02X%02X%02X%02X%02X%02X%02X", snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7]);

  if (snr != sprox_ctx->iso15693_snr)
  {
    memset(sprox_ctx->iso15693_snr, 0, sizeof(sprox_ctx->iso15693_snr));
    if (snr != NULL)
      memcpy(sprox_ctx->iso15693_snr, snr, 8);
  }
  return MI_OK;
}

/**f* SpringProxAPI/SPROX_Iso15693_SelectAny
 *
 * NAME
 *   SPROX_Iso15693_SelectAny
 *
 * DESCRIPTION
 *   Select "Any" ISO 15693 card available in the RF field
 *
 * INPUTS
 *   BOOL fast_mode     : RF setting mode (TRUE = fast mode, False = standard mode)
 *   BYTE snr[8]        : 8-byte buffer to receive card's Unique ID
 *
 * RETURNS
 *   MI_OK              : success, card selected
 *   MI_NOTAGERR        : no card available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 *
 * SEE ALSO
 *   SPROX_Iso15693_SelectAgain
 *   SPROX_Iso15693_Halt
 *
 **/
SPROX_API_FUNC(Iso15693_SelectAny) (SPROX_PARAM  BOOL fast_mode, BYTE snr[8])
{
  SWORD rc;
  BYTE  buffer[8];
  WORD  len = sizeof(buffer);
  SPROX_PARAM_TO_CTX;  
  
  if (snr == NULL) return MI_LIB_CALL_ERROR;
  
  if (fast_mode)
    sprox_ctx->iso15693_mode = CFG_MODE_ISO_15693_FAST;
  else 
    sprox_ctx->iso15693_mode = CFG_MODE_ISO_15693_STD;
    
  rc = SPROX_API_CALL(SetConfig) (SPROX_PARAM_P  sprox_ctx->iso15693_mode);
  if ((rc != MI_OK) && (rc != MI_UNKNOWN_FUNCTION)) return rc;

  rc = SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_SELECT_ANY, NULL, 0, buffer, &len);
  if (rc == MI_OK)
  {
    Save15693Snr(SPROX_PARAM_P  &buffer[0]);

    if (snr != NULL)
      memcpy(snr, &buffer[0], 8);
  }

  SPROX_Trace(TRACE_DEBUG, "15693_SelectAny %02X%02X%02X%02X%02X%02X%02X%02X -> %d", snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7], rc);

  return rc; 
}

/**f* SpringProxAPI/SPROX_Iso15693_SelectAgain
 *
 * NAME
 *   SPROX_Iso15693_SelectAgain
 *
 * DESCRIPTION
 *   Allow to re-select an ISO 15693 card, provided its serial number.
 *
 * INPUTS
 *   BYTE snr[8]        : 8-byte buffer to receive card's Unique ID
 *
 * RETURNS
 *   MI_OK              : success, card selected
 *   MI_NOTAGERR        : the required card is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_Iso15693_SelectAny
 *   SPROX_Iso15693_Halt
 *
 **/
SPROX_API_FUNC(Iso15693_SelectAgain) (SPROX_PARAM  BYTE snr[8])
{
  SWORD rc;
  SPROX_PARAM_TO_CTX;

  rc = SPROX_API_CALL(SetConfig) (SPROX_PARAM_P  sprox_ctx->iso15693_mode);
  if ((rc != MI_OK) && (rc != MI_UNKNOWN_FUNCTION)) return rc;

  if (snr == NULL)
    snr = sprox_ctx->iso15693_snr;
     
  rc = SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_SELECT_AGAIN, snr, 8, NULL, NULL);
  
  if ((rc == MI_OK) && (snr != sprox_ctx->iso15693_snr))
    Save15693Snr(SPROX_PARAM_P  snr);

  SPROX_Trace(TRACE_DEBUG, "15693_SelectAgain %04X%04X%04X%04X%04X%04X%04X%04X -> %d", snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7], rc);

  return rc; 
}

/**f* SpringProxAPI/SPROX_Iso15693_Halt
 *
 * NAME
 *   SPROX_Iso15693_Halt
 *
 * DESCRIPTION
 *   Send the ISO 15693 HALT command to the currently selected card.
 *
 * INPUTS
 *   none
 *
 * RETURNS
 *   MI_OK              : success, card halted
 *   Other code if internal or communication error has occured. 
 * 
 * SEE ALSO
 *   SPROX_Iso15693_SelectAny
 *   SPROX_Iso15693_SelectAgain
 *
 **/
SPROX_API_FUNC(Iso15693_Halt) (SPROX_PARAM_V)
{
  SPROX_PARAM_TO_CTX;
  
  SPROX_API_CALL(SetConfig) (SPROX_PARAM_P  sprox_ctx->iso15693_mode);  
  
  return SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_HALT, NULL, 0, NULL, NULL);  
}

/*
 * Internal function to read or write a block
 * ------------------------------------------
 */
static SWORD Iso15693_RWBlock(SPROX_PARAM  BOOL w, BOOL s, BOOL mbloc, BYTE snr[8], BYTE bloc, BYTE nb_bloc, BYTE data[], WORD *datalen)
{
  SWORD rc;
  
  rc = MI_LIB_CALL_ERROR;
  if (data == NULL)
    goto exit_proc;

  if (snr != NULL)
  {
    rc = SPROX_API_CALL(Iso15693_SelectAgain) (SPROX_PARAM_P  snr);
    if (rc != MI_OK)
      goto exit_proc;
  }

  if (w)
  {
    BYTE buffer[256];
	WORD len = *datalen + 1;
    buffer[0] = bloc;
    memcpy(&buffer[1], data, *datalen);
    rc = SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_WRITE, buffer, len, NULL, NULL);
  } else
  {
    BYTE buffer[3];
    WORD len = 0;
    
    if (s)
    {
      len = 1;
      buffer[0] = bloc;
    } else
    {
      if (mbloc)
      {
        len = 3;
        buffer[0] = bloc;
        buffer[1] = 0x00;
        buffer[2] = nb_bloc;
      } else
      {
        len = 3;
        buffer[0] = bloc;
        buffer[1] = 0x01;
        buffer[2] = (BYTE)*datalen;
      }
    }
      
    rc = SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_READ, buffer, len, data, datalen);
  }

exit_proc:
  if (snr != NULL)
    SPROX_Trace(TRACE_DEBUG, "15693%sBlock %d %04X%04X%04X%04X%04X%04X%04X%04X -> %d", w ? "Write" : "Read", bloc, snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7], rc);
  else
    SPROX_Trace(TRACE_DEBUG, "15693%sBlock %d -> %d", w ? "Write" : "Read", bloc, rc);

  return rc;
}

/**f* SpringProxAPI/SPROX_Iso15693_ReadSingleBlock
 *
 * NAME
 *   SPROX_Iso15693_ReadSingleBlock
 *
 * DESCRIPTION
 *   Read one block of a ISO 15693 tag.
 *
 * INPUTS
 *   const BYTE snr[8]   : 8-byte UID of the ISO 15693 card to read
 *                         If NULL, the reader will work with currently selected tag
 *   BYTE bloc           : address of the block to read
 *   BYTE data[]         : buffer to receive the data
 *   WORD *datalen       : length of the receive data
 *
 * WARNING
 *   The number of blocks available on a ISO 15693 tag depends on the tag type.
 *
 *   For example, a ISO 15693 ICODE-SLI tag stores 28 blocks (address 0 to 27), a
 *   ISO 15693 ICODE-SLI-L tag stores 8 blocks (address 0 to 7), a ISO 15693 Tag-It
 *   Plus Inlay tag stores 64 blocks (address 0 to 63).
 *
 *   For more details, please refer to specific tag documentation.
 *
 * RETURNS
 *   MI_OK              : success, data have been read
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_Iso15693_ReadMultipleBlocks
 *   SPROX_Iso15693_ReadMultipleBytes
 *   SPROX_Iso15693_WriteBlock
 *   SPROX_Iso15693_LockBlock
 *
 **/
SPROX_API_FUNC(Iso15693_ReadSingleBlock) (SPROX_PARAM  BYTE snr[8], BYTE bloc, BYTE data[], WORD *datalen)
{
  return Iso15693_RWBlock(SPROX_PARAM_P  FALSE, TRUE, FALSE, snr, bloc, 0x01, data, datalen);
}

/**f* SpringProxAPI/SPROX_Iso15693_ReadMultipleBlocks
 *
 * NAME
 *   SPROX_Iso15693_ReadMultipleBlocks
 *
 * DESCRIPTION
 *   Read multiple blocks of a ISO 15693 tag, using the "read multiple blocks" command.
 *
 * INPUTS
 *   const BYTE snr[8]   : 8-byte UID of the ISO 15693 card to read
 *                         If NULL, the reader will work with currently selected tag
 *   BYTE bloc           : address of the first block to read
 *   BYTE nb_bloc        : number of blocks to read
 *   BYTE data[]         : buffer to receive the data
 *   WORD *datalen       : length of the receive data
 *
 * WARNING
 *   The number of blocks available on a ISO 15693 tag depends on the tag type.
 *
 *   For example, a ISO 15693 ICODE-SLI tag stores 28 blocks (address 0 to 27), a
 *   ISO 15693 ICODE-SLI-L tag stores 8 blocks (address 0 to 7), a ISO 15693 Tag-It
 *   Plus Inlay tag stores 64 blocks (address 0 to 63).
 *
 *   For more details, please refer to specific tag documentation.
 *
 * RETURNS
 *   MI_OK              : success, data have been read
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_Iso15693_ReadSingleBlock
 *   SPROX_Iso15693_ReadMultipleBytes
 *   SPROX_Iso15693_WriteBlock
 *   SPROX_Iso15693_LockBlock
 *
 **/
SPROX_API_FUNC(Iso15693_ReadMultipleBlocks) (SPROX_PARAM  BYTE snr[8], BYTE bloc, BYTE nb_bloc, BYTE data[], WORD *datalen)
{
  return Iso15693_RWBlock(SPROX_PARAM_P  FALSE, FALSE, TRUE, snr, bloc, nb_bloc, data, datalen);
}

/**f* SpringProxAPI/SPROX_Iso15693_ReadMultipleBytes
 *
 * NAME
 *   SPROX_Iso15693_ReadMultipleBytes
 *
 * DESCRIPTION
 *   Read multiple bytes of a ISO 15693 tag.
 *
 * INPUTS
 *   const BYTE snr[8]   : 8-byte UID of the ISO 15693 card to read
 *                         If NULL, the reader will work with currently selected tag
 *   BYTE bloc           : address of the first block to read
 *   BYTE data[]         : buffer to receive the data
 *   WORD *datalen       : length of the receive data
 *
 * WARNING
 *   The number of blocks available on a ISO 15693 tag depends on the tag type.
 *
 *   For example, a ISO 15693 ICODE-SLI tag stores 28 blocks (address 0 to 27), a
 *   ISO 15693 ICODE-SLI-L tag stores 8 blocks (address 0 to 7), a ISO 15693 Tag-It
 *   Plus Inlay tag stores 64 blocks (address 0 to 63).
 *
 *   For more details, please refer to specific tag documentation.
 *
 * RETURNS
 *   MI_OK              : success, data have been read
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_Iso15693_ReadSingleBlock
 *   SPROX_Iso15693_ReadMultipleBlocks
 *   SPROX_Iso15693_WriteBlock
 *   SPROX_Iso15693_LockBlock
 *
 **/
SPROX_API_FUNC(Iso15693_ReadMultipleBytes) (SPROX_PARAM  BYTE snr[8], BYTE bloc, BYTE data[], WORD *datalen)
{
  return Iso15693_RWBlock(SPROX_PARAM_P  FALSE, FALSE, FALSE, snr, bloc, 0, data, datalen);
}

/**f* SpringProxAPI/SPROX_Iso15693_WriteBlock
 *
 * NAME
 *   SPROX_Iso15693_WriteBlock
 *
 * DESCRIPTION
 *   Write bytes in a block of a ISO 15693 tag.
 *
 * INPUTS
 *   const BYTE snr[8]  : 8-byte UID of the ISO 15693 card to read
 *                        If NULL, the reader will work with currently selected tag
 *   BYTE bloc          : address of the block to write
 *   BYTE data[]        : buffer of data
 *   WORD datalen       : length of data
 *
 * RETURNS
 *   MI_OK              : success, data have been written
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_15693_IsoReadBlock
 *   SPROX_15693_IsoLockBlock
 *
 **/
SPROX_API_FUNC(Iso15693_WriteBlock) (SPROX_PARAM  BYTE snr[8], BYTE bloc, BYTE data[], WORD datalen)
{
  return Iso15693_RWBlock(SPROX_PARAM_P  TRUE, FALSE, FALSE, snr, bloc, 0, data, &datalen);
}

/**f* SpringProxAPI/SPROX_Iso15693_LockBlock
 *
 * NAME
 *   SPROX_Iso15693_LockBlock
 *
 * DESCRIPTION
 *   Lock permanently one 4-byte block of a ISO 15693 tag.
 *
 * INPUTS
 *   const BYTE snr[8]  : 8-byte UID of the ISO 15693 card to read
 *                        If NULL, the reader will work with currently selected tag
 *   BYTE bloc          : address of the block to write
 *
 * WARNING
 *   When a block is locked, it will be imposssible to change the value of block again.
 *
 *   For more details, please refer to specific tag documentation.
 *
 * RETURNS
 *   MI_OK              : success, data have been written
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_15693_IsoWriteBlock
 *   SPROX_15693_IsoReadBlock
 *
 **/
SPROX_API_FUNC(Iso15693_LockBlock) (SPROX_PARAM  BYTE snr[8], BYTE bloc)
{
  SWORD   rc;
  
  rc = MI_LIB_CALL_ERROR;

  if (snr != NULL)
  {
    rc = SPROX_API_CALL(Iso15693_SelectAgain) (SPROX_PARAM_P  snr);
    if (rc != MI_OK)
      goto exit_proc;
  }

  rc = SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_LOCK, &bloc, 1, NULL, NULL);

exit_proc:
  if (snr != NULL)
    SPROX_Trace(TRACE_DEBUG, "15693_LockBlock %d %04X%04X%04X%04X%04X%04X%04X%04X -> %d", bloc, snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7], rc);
  else
    SPROX_Trace(TRACE_DEBUG, "15693_LockBlock %d -> %d", bloc, rc);

  return rc;
}

/**f* SpringProxINS/Iso15693_GetSystemInformation
 *
 * SYNOPSIS
 *   SBYTE Iso15693_GetSystemInformation(BYTE *data, WORD *datalen)
 *
 * DESCRIPTION
 *   Get system information in a ISO 15693 tag.
 *   The target card is the currently selected one (which params are loaded
 *   into vicc_tag).
 *
 * INPUTS
 *   const BYTE snr[8]  : 8-byte UID of the ISO 15693 card to read
 *                         If NULL, the reader will work with currently selected tag
 *   BYTE *data         : data buffer (out)
 *   WORD *datalen      : length of data buffer (in or out)
 *
 * WARNING
 *   For more details, please refer to specific tag documentation.
 *
 * RETURNS
 *   MI_OK              : success, data have been read
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_Iso15693_ReadMultipleBlocks
 *   SPROX_Iso15693_ReadMultipleBytes
 *   SPROX_Iso15693_WriteBlock
 *   SPROX_Iso15693_LockBlock
 *
 **/
SPROX_API_FUNC(Iso15693_GetSystemInformation) (SPROX_PARAM  BYTE snr[8], BYTE data[], WORD *datalen)
{
  SWORD   rc;
  
  rc = MI_LIB_CALL_ERROR;

  if (snr != NULL)
  {
    rc = SPROX_API_CALL(Iso15693_SelectAgain) (SPROX_PARAM_P  snr);
    if (rc != MI_OK)
      goto exit_proc;
  }

  rc = SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_GET_SYSTEM_INFO, NULL, 0, data, datalen);

exit_proc:
  if (snr != NULL)
    SPROX_Trace(TRACE_DEBUG, "Iso15693_GetSystemInformation %04X%04X%04X%04X%04X%04X%04X%04X -> %d", snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7], rc);
  else
    SPROX_Trace(TRACE_DEBUG, "Iso15693_GetSystemInformation -> %d", rc);
    
  return rc;
}


/*
 *
 * ICODE1
 *
 */

SWORD SaveI1Snr(SPROX_PARAM  BYTE snr[8])
{
  SPROX_PARAM_TO_CTX;
  SPROX_Trace(TRACE_DEBUG, "15693Snr <- %02X%02X%02X%02X%02X%02X%02X%02X", snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7]);

  if (snr != sprox_ctx->i1_snr)
  {
    memset(sprox_ctx->i1_snr, 0, sizeof(sprox_ctx->i1_snr));
    if (snr != NULL)
      memcpy(sprox_ctx->i1_snr, snr, 8);
  }
  return MI_OK;
}

/**f* SpringProxAPI/SPROX_I1_SelectAny
 *
 * NAME
 *   SPROX_I1_SelectAny
 *
 * DESCRIPTION
 *   Select "Any" ISO 15693 card available in the RF field
 *
 * INPUTS
 *   BOOL fast_mode     : RF setting mode (TRUE = fast mode, False = standard mode)
 *   BYTE snr[8]        : 8-byte buffer to receive card's Unique ID
 *
 * RETURNS
 *   MI_OK              : success, card selected
 *   MI_NOTAGERR        : no card available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_I1_SelectAny
 *   SPROX_I1_Write
 *   SPROX_I1_Read
 *
 **/
SPROX_API_FUNC(I1_SelectAny) (SPROX_PARAM  BOOL fast_mode, BYTE snr[8])
{
  SWORD rc;
  BYTE  buffer[8];
  WORD  len = sizeof(buffer);
  SPROX_PARAM_TO_CTX;  

  if (snr == NULL) return MI_LIB_CALL_ERROR;
  
  if (fast_mode)
    sprox_ctx->i1_mode = CFG_MODE_ICODE1_FAST;
  else 
    sprox_ctx->i1_mode = CFG_MODE_ICODE1_STD;
    
  rc = SPROX_API_CALL(SetConfig) (SPROX_PARAM_P  sprox_ctx->i1_mode);
  if ((rc != MI_OK) && (rc != MI_UNKNOWN_FUNCTION)) return rc;

  rc = SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_SELECT_ANY, NULL, 0, buffer, &len);
  if (rc == MI_OK)
  {
    SaveI1Snr(SPROX_PARAM_P  &buffer[0]);

    if (snr != NULL)
      memcpy(snr, &buffer[0], 8);
  }

  SPROX_Trace(TRACE_DEBUG, "I1_SelectAny %04X%04X%04X%04X%04X%04X%04X%04X -> %d", snr[0], snr[1], snr[2], snr[3], snr[4], snr[5], snr[6], snr[7], rc);

  return rc; 
}

/**f* SpringProxAPI/SPROX_I1_Halt
 *
 * NAME
 *   SPROX_I1_Halt
 *
 * DESCRIPTION
 *   Send the ICODE1 HALT command to the currently selected card.
 *
 * INPUTS
 *   none
 *
 * RETURNS
 *   MI_OK              : success, card halted
 *   Other code if internal or communication error has occured. 
 * 
 * SEE ALSO
 *   SPROX_I1_SelectAny
 *   SPROX_I1_Write
 *   SPROX_I1_Read
 *
 **/
SPROX_API_FUNC(I1_Halt) (SPROX_PARAM_V)
{
  SPROX_PARAM_TO_CTX;
  
  SPROX_API_CALL(SetConfig) (SPROX_PARAM_P  sprox_ctx->i1_mode);  
  
  return SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_HALT, NULL, 0, NULL, NULL);  
}


/**f* SpringProxAPI/SPROX_I1_Read
 *
 * NAME
 *   SPROX_I1_Read
 *
 * DESCRIPTION
 *   Read multiple blocks of a ICODE1 tag.
 *
 * INPUTS
 *   BYTE bloc           : address of the first block to read
 *   BYTE nb_bloc        : number of blocks to read
 *   const BYTE *data    : buffer to receive the data
 *   const WORD *datalen : length of the receive data
 *
 * RETURNS
 *   MI_OK              : success, data have been read
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_I1_SelectAny
 *   SPROX_I1_Halt
 *   SPROX_I1_Write
 *
 **/
SPROX_API_FUNC(I1_Read) (SPROX_PARAM  BYTE bloc, BYTE nb_bloc, BYTE data[], WORD *datalen)
{
  BYTE buffer[2];
  buffer[0] = bloc;
  buffer[1] = nb_bloc;      
  return SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_READ, buffer, 2, data, datalen);
}


/**f* SpringProxAPI/SPROX_I1_Write
 *
 * NAME
 *   SPROX_I1_Write
 *
 * DESCRIPTION
 *   Write bytes in a block of a ICODE1 tag.
 *
 * INPUTS
 *   BYTE bloc          : address of the block to write
 *   BYTE data[4]       : buffer of data
 *
 * RETURNS
 *   MI_OK              : success, data have been written
 *   MI_NOTAGERR        : the required tag is not available in the RF field
 *   Other code if internal or communication error has occured. 
 *
 * SEE ALSO
 *   SPROX_I1_SelectAny
 *   SPROX_I1_Halt
 *   SPROX_I1_Read
 *
 **/
SPROX_API_FUNC(I1_Write) (SPROX_PARAM BYTE bloc, BYTE data[4])
{
  BYTE buffer[5];
  buffer[0] = bloc;
  memcpy(&buffer[1], data, 4);
  return SPROX_DLG_FUNC(SPROX_PARAM_P  SPROX_CSB_WRITE, buffer, 5, NULL, NULL);
}
